use crate::{git_config_get, git_read_tag};
use git2::{Commit, Repository};
use serde::{Deserialize, Serialize};
/// git commit实体
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GitCommit {
    /// 提交id
    ///
    /// ## 示例: "92939508f87af17465e9274d245815edc9b764ca"
    pub commit_id: String,
    /// 提交信息
    ///
    /// ## 示例: "initial commit"
    pub message: String,
    /// 提交时间戳
    ///
    /// ## 示例: 1739783276
    pub time: i64,
    /// tag名称
    ///
    /// ## 示例: v1.2.3
    pub tag: Option<String>,
}
/// git commit -m "This is commit message"
pub fn git_commit(repo: &Repository, msg: &str) -> anyhow::Result<()> {
    let mut index = repo.index()?;
    let tree_id = index.write_tree()?;
    let tree = repo.find_tree(tree_id)?;
    let (_, _, _, sig) = git_config_get(&repo)?;
    let parent_commit = if let Ok(parent_commit) = repo.head().and_then(|r| r.peel_to_commit()) {
        //获取最新的提交作为父提交，如果有父提交则返回
        Some(parent_commit)
    } else {
        //如果是第一次提交则返回None
        None
    };
    let parents: Vec<&Commit> = parent_commit.as_ref().into_iter().collect();
    repo.commit(Some("HEAD"), &sig, &sig, msg, &tree, &parents)?;
    Ok(())
}

/// 查询git提交记录
pub fn git_read_commits(repo: &Repository) -> anyhow::Result<Vec<GitCommit>> {
    let tags = git_read_tag(repo)?;
    let mut rev_walk = repo.revwalk()?;
    rev_walk.push_head()?;
    // rev_walk.set_sorting(Sort::REVERSE).unwrap();
    let mut r = vec![];
    for oid in rev_walk {
        let commit = repo.find_commit(oid?)?;
        let commit_id = commit.id().to_string();
        let option = tags
            .iter()
            .find(|tag| tag.commit_id == commit_id)
            .and_then(|t| Some((*t.name).to_string()));
        let commit = GitCommit {
            commit_id,
            message: commit.message().unwrap().to_string(),
            time: commit.time().seconds(),
            tag: option,
        };
        r.push(commit);
    }
    Ok(r)
}
